package org.openbpm.bpm.engine.action.handler.instance;

import org.apache.commons.lang3.StringUtils;
import org.openbpm.base.api.exception.BusinessMessage;
import org.openbpm.bpm.act.service.ActInstanceService;
import org.openbpm.bpm.api.constant.ActionType;
import org.openbpm.bpm.api.constant.InstanceStatus;
import org.openbpm.bpm.api.engine.action.cmd.ActionCmd;
import org.openbpm.bpm.api.engine.action.handler.BuiltinActionHandler;
import org.openbpm.bpm.api.engine.context.BpmContext;
import org.openbpm.bpm.api.exception.BpmStatusCode;
import org.openbpm.bpm.api.model.def.IBpmDefinition;
import org.openbpm.bpm.api.model.inst.IBpmInstance;
import org.openbpm.bpm.api.model.nodedef.BpmNodeDef;
import org.openbpm.bpm.core.manager.BpmDefinitionManager;
import org.openbpm.bpm.core.manager.BpmInstanceManager;
import org.openbpm.bpm.core.model.BpmInstance;
import org.openbpm.bpm.engine.action.cmd.DefaultInstanceActionCmd;
import org.openbpm.sys.util.ContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Component("instanceRestartActionHandler")
public class InstanceRestartActionHandler implements BuiltinActionHandler<DefaultInstanceActionCmd> {
    @Autowired
    private BpmInstanceManager bpmInstanceManager;

    @Autowired
    private ActInstanceService actInstanceService;

    @Autowired
    private BpmDefinitionManager bpmDefinitionManager;

    public boolean isDisplay(boolean readOnly, BpmNodeDef bpmNodeDef, IBpmInstance bpmInstance) {
        if (bpmInstance == null || !ContextUtil.currentUserIsAdmin())
            return false;
        return isInstEnd(bpmInstance);
    }

    private boolean isInstEnd(IBpmInstance bpmInstance) {
        return StringUtils.equalsAny(bpmInstance.getStatus(), new CharSequence[] { InstanceStatus.STATUS_END
                .getKey(), InstanceStatus.STATUS_MANUAL_END
                .getKey() });
    }

    @Override
    public void execute(DefaultInstanceActionCmd model) {
        if (!ContextUtil.currentUserIsAdmin())
            throw new BusinessMessage("操作受限，您没有该操作权限", BpmStatusCode.NO_PERMISSION);
        BpmInstance bpmInstance = (BpmInstance)this.bpmInstanceManager.get(model.getInstanceId());
        if (bpmInstance == null)
            throw new BusinessMessage("操作流程实例不存在");
        if (!isInstEnd((IBpmInstance)bpmInstance))
            throw new BusinessMessage("操作流程实例已在运行中");
        String destination = model.getDestination();
        bpmInstance.setActInstId(null);
        model.setBpmInstance((IBpmInstance)bpmInstance);
        model.setBpmDefinition((IBpmDefinition)this.bpmDefinitionManager.get(bpmInstance.getDefId()));
        try {
            String actInstId;
            BpmContext.setActionModel((ActionCmd)model);
            if (StringUtils.isEmpty(destination)) {
                actInstId = this.actInstanceService.startProcessInstance(bpmInstance.getActDefId(), bpmInstance.getBizKey(), model.getActionVariables());
            } else {
                actInstId = this.actInstanceService.startProcessInstance((IBpmInstance)bpmInstance, model.getActionVariables(), new String[] { destination });
            }
            bpmInstance.setActInstId(actInstId);
            bpmInstance.setStatus(InstanceStatus.STATUS_RUNNING.getKey());
            bpmInstance.setDuration(null);
            bpmInstance.setEndTime(null);
            this.bpmInstanceManager.update(bpmInstance);
        } finally {
            BpmContext.cleanTread();
        }
    }



    public ActionType getActionType() {
        return ActionType.INSTANCE_RESTART;
    }

    public int getSn() {
        return 9;
    }

    public Boolean isSupport(BpmNodeDef nodeDef) {
        return Boolean.FALSE;
    }

    public Boolean isDefault() {
        return Boolean.TRUE;
    }

    public String getConfigPage() {
        return "/bpm/instance/instanceRestartOpinionDialog.html";
    }

    public String getDefaultGroovyScript() {
        return null;
    }

    public String getDefaultBeforeScript() {
        return null;
    }
}
